struct Squares
   count::Int
end
Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1)
for i in Squares(7)
   println(i)
end
println("in:", 25 in Squares(10))

using Statistics
println("mean:", mean(Squares(3)))
println("std:", std(Squares(3)))

Base.length(S::Squares) = S.count
println("length:", length(Squares(10)))
println("collect:", collect(Squares(4)))

Base.sum(S::Squares) = (n = S.count; return n*(n+1)*(2n+1)÷6)
println("sum:", sum(Squares(1803)))

Base.iterate(rS::Iterators.Reverse{Squares}, state=rS.itr.count) = state < 1 ? nothing : (state*state, state-1)
println("reverse:", collect(Iterators.reverse(Squares(4))))

function Base.getindex(S::Squares, i::Int)
   1 <= i <= S.count || throw(BoundsError(S, i))
   return i*i
end
Base.getindex(S::Squares, i::Number) = S[convert(Int, i)]
Base.getindex(S::Squares, I) = [S[i] for i in I]
println("getindex:", Squares(100)[23])

Base.firstindex(S::Squares) = 1
Base.lastindex(S::Squares) = length(S)
println("end:", Squares(23)[end])


println("--------SquaresVector:")
struct SquaresVector <: AbstractArray{Int, 1}
  count::Int
end
Base.size(S::SquaresVector) = (S.count,)
Base.IndexStyle(::Type{<:SquaresVector}) = IndexLinear()
Base.getindex(S::SquaresVector, i::Int) = i*i
s = SquaresVector(4)
println("SquaresVector:", s)
println(".>:", s[s .> 8])
println("+:", s + s)
println("sin.(s):", sin.(s))
